package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.MovementApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.MovementsVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class MovementService {

    @Autowired
    OssTemplate ossTemplate;

    @DubboReference
    MovementApi movementApi;

    @DubboReference
    UserInfoApi userInfoApi;

    @Autowired
    RedisTemplate<String, String> redisTemplate;


    public void publishMovement(Movement movement, MultipartFile[] imageContent) throws IOException {
//1、判断发布动态的内容是否存在
        if (StringUtils.isEmpty(movement.getTextContent())) {
            throw new BusinessException(ErrorResult.contentEmpty());
        }
        //2、获取当前登录的用户id
        Long userId = UserHolder.getUserId();
        //3、将文件内容上传到阿里云OSS，获取请求地址
        List<String> medias = new ArrayList<>();
        for (MultipartFile multipartFile : imageContent) {
            String upload = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
            medias.add(upload);
        }
        //4、将数据封装到Movement对象
        movement.setUserId(userId);
        movement.setMedias(medias);
        //5、调用API完成发布动态
        movementApi.publish(movement);
    }

    //查询个人动态
    public PageResult findByUserId(Long userId, Integer page, Integer pagesize) {
        //1、根据用户id，调用API查询个人动态内容（PageResult  -- Movement）
        PageResult pr = movementApi.findByUserId(userId, page, pagesize);
        //2、获取PageResult中的item列表对象
//        List<Movement> items = (List<Movement>) pr.getItems();
//        //3、非空判断
//        if (items == null) {
//            return pr;
//        }
//        //4、循环数据列表
//        UserInfo userInfo = userInfoApi.findById(userId);
//        List<MovementsVo> vos = new ArrayList<>();
//        for (Movement item : items) {
//            //5、一个Movement构建一个Vo对象
//            MovementsVo vo = MovementsVo.init(userInfo, item);
//            vos.add(vo);
//        }
//        //6、构建返回值
//        pr.setItems(vos);
        PageResult pageResult = getPageResult(page, pagesize, pr);
        return pageResult;
    }

    public PageResult findFriendMovements(Integer page, Integer pagesize) {
        //1去时间线表查询当前好友发送的动态id 根据动态id查询动态
        Long userId = UserHolder.getUserId();
        PageResult<Movement> result = movementApi.findFriendMovements(page, pagesize, userId);
        PageResult pageResult = getPageResult(page, pagesize, result);
        return pageResult;
    }

    //抽取公共方法
    private PageResult getPageResult(Integer page, Integer pagesize, PageResult<Movement> originPageResult) {
        List<Movement> list = originPageResult.getItems();
        if (CollUtil.isEmpty(list)) {
            return new PageResult();
        }
        //4、提取动态发布人的id列表
        List<Long> userIds = CollUtil.getFieldValues(list, "userId", Long.class);
        //5、根据用户的id列表获取用户详情
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);
        //6、一个Movement构造一个vo对象
        List<MovementsVo> vos = new ArrayList<>();
        for (Movement movement : list) {
            UserInfo userInfo = map.get(movement.getUserId());
            if (userInfo != null) {
                MovementsVo vo = MovementsVo.init(userInfo, movement);
                vos.add(vo);
            }
        }
        //7、构造PageResult并返回
        return new PageResult(page, pagesize, originPageResult.getCounts(), vos);
    }

    public PageResult findRecommendMovements(Integer page, Integer pagesize) {
        //1、从redis中获取推荐数据
        String recommendKey = Constants.MOVEMENTS_RECOMMEND + UserHolder.getUserId();
        String recommendValue = redisTemplate.opsForValue().get(recommendKey);
        //2、判断推荐数据是否存在
        List<Movement> list = Collections.EMPTY_LIST;
        int count = 0;
        if (StringUtils.isEmpty(recommendValue)) {
            //3、如果不存在，调用API随机构造10条动态数据
            list = movementApi.randomMovements(pagesize);
            count = list.size();
        } else {
            String[] values = recommendValue.split(",");
            count = values.length;
            //判断当前页的起始条数是否小于数组总数
            if ((page - 1) * pagesize < values.length) {
                List<Long> pids = Arrays.stream(values).skip((page - 1) * pagesize).limit(pagesize)
                        .map(new Function<String, Long>() {
                            @Override
                            public Long apply(String s) {
                                return Long.valueOf(s);
                            }
                        }).collect(Collectors.toList());
                //5、调用API根据PID数组查询动态数据
                list = movementApi.findMovementsByPids(pids);
            }
        }
        //根据查到的动态信息 组装成用户信息
        PageResult pageResult = getPageResult(page, pagesize, new PageResult<>(page, pagesize, count, list));
        return pageResult;
    }

    public MovementsVo findById(String movementId) {
        //1、调用api根据id查询动态详情
        Movement movement = movementApi.findById(movementId);
        //2、转化vo对象
        if(movement != null) {
            UserInfo userInfo = userInfoApi.findById(movement.getUserId());
            return MovementsVo.init(userInfo,movement);
        }else {
            return null;
        }
    }
}
